## GB/T 19056-2021

from collections import OrderedDict


class VDR_OBJECT(object):
    '''
    vdr_filepath: vdr记录的路径名
    standard_year: 记录仪执行标准年号（表A.6）
    driver_info: 当前驾驶人信息（表A.7）
    temp_time: 记录仪实时时间（表A.8）
    cumlative_mileage: 累计行驶里程（表A.9）
    '''
    def __init__(self, vdr_filepath):
        self.vdr_filepath = vdr_filepath
#        self.vdr_dict = OrderedDict()
        self.__decode()
    
    def __decode(self):
        with open(self.vdr_filepath,'rb') as f:
            self.datablock_num = VDR_DATABLOCK_NUM(f.read(2)) #读取数据块个数
            """然后是若干个数据块，每个数据块由1个字节的数据代码，18个字节的数据名称，4个字节的数据长度和若干字节的数据记录组成"""
            for n in range(0,self.datablock_num.data):
                datacode = f.read(1).hex() # 数据代码
                dataname = f.read(18).decode('gb2312')
                datalength = int.from_bytes(f.read(4),byteorder='big',signed=False)
                if datacode == '00': # 记录仪执行标准年号
                    year = f.read(1).hex() # 第一个字节是记录仪执行标准年号后2位
                    danhao = f.read(1) # 第二个字节是修改单号
                    self.standard_year = VDR_STANDARD_YEAR(dataname,datalength,year,danhao)
                elif datacode == '01': # 当前驾驶人信息
                    driver_card_no = f.read(18).decode('utf-8')
                    self.driver_info = VDR_DRIVER_INFO(dataname, datalength, driver_card_no)
                elif datacode == '02': # 记录仪实时时间
                    year = f.read(1).hex() # 年
                    month = f.read(1).hex() # 月
                    day = f.read(1).hex() # 日
                    hour = f.read(1).hex() # 时
                    minute = f.read(1).hex() # 分
                    second = f.read(1).hex() # 秒
                    self.temp_time = VDR_TEMP_TIME(dataname, datalength, year, month, day, hour, minute, second)
                elif datacode == '03': # 累计行驶里程
                    year1 = f.read(1).hex() # 年
                    month1 = f.read(1).hex() # 月
                    day1 = f.read(1).hex() # 日
                    hour1 = f.read(1).hex() # 时
                    minute1 = f.read(1).hex() # 分
                    second1 = f.read(1).hex() # 秒
                    year2 = f.read(1).hex() # 年
                    month2 = f.read(1).hex() # 月
                    day2 = f.read(1).hex() # 日
                    hour2 = f.read(1).hex() # 时
                    minute2 = f.read(1).hex() # 分
                    second2 = f.read(1).hex() # 秒
                    init_mileage = f.read(4).hex() # 初始里程
                    cumlative_mileage = f.read(4).hex() # 累计行驶里程
                    self.cumlative_mileage = VDR_CUMULATIVE_MILEAGE(dataname, datalength, year1, month1, day1, hour1, minute1, second1, year2, month2, day2, hour2, minute2, second2, init_mileage, cumlative_mileage)
                elif datacode == '04': # 记录仪脉冲系数
                    year = f.read(1).hex() # 年
                    month = f.read(1).hex() # 月
                    day = f.read(1).hex() # 日
                    hour = f.read(1).hex() # 时
                    minute = f.read(1).hex() # 分
                    second = f.read(1).hex() # 秒
                    pulse = int.from_bytes(f.read(2),byteorder='big',signed=False) #记录仪脉冲系数高字节和低字节
                    self.pulse = VDR_PULSE(dataname, datalength, year, month, day, hour, minute, second, pulse)
                elif datacode == '05': # 车辆信息
                    recognization_no = f.read(17).decode('utf-8')
                    license_no = f.read(12).decode('gb2312')
                    license_type = f.read(12).decode('gb2312')
                    self.vehicle_info = VDR_VEHICLE_INFO(dataname, datalength, recognization_no, license_no, license_type)
                elif datacode == '06': # 记录仪状态信号配置信息
                    year = f.read(1).hex() # 年
                    month = f.read(1).hex() # 月
                    day = f.read(1).hex() # 日
                    hour = f.read(1).hex() # 时
                    minute = f.read(1).hex() # 分
                    second = f.read(1).hex() # 秒
                    signal_count = f.read(1).hex() # 状态信号字节个数
                    print(signal_count)
                    D7 = f.read(10).decode('gb2312')
                    D6 = f.read(10).decode('gb2312')
                    D5 = f.read(10).decode('gb2312')
                    D4 = f.read(10).decode('gb2312')
                    D3 = f.read(10).decode('gb2312')
                    D2 = f.read(10).decode('gb2312')
                    D1 = f.read(10).decode('gb2312')
                    D0 = f.read(10).decode('gb2312')
                    print(D7,D6,D5,D4,D3,D2,D1,D0)
                elif datacode == '07': # 记录仪唯一性编号
                    identify_no = f.read(7).decode('utf-8')
                    print(identify_no)
                    product_no = f.read(16).decode('utf-8')
                    print(product_no)
                    year = f.read(1).hex() # 年
                    month = f.read(1).hex() # 月
                    day = f.read(1).hex() # 日
                    # water_no = f.read(4).hex() # 转成10
                    water_no = int.from_bytes(f.read(4),byteorder='big',signed=True) #  产品生产流水号,不足8位要补0
                    spare = f.read(5) # 备用字节
                    print(water_no,spare)
                    break
                    
            


class VDR_DATABLOCK_NUM(object):
    '''
    数据块个数
    data:数据
    status:1代表正确，0代表待定，-1代表错误
    help:帮助信息
    '''
    def __init__(self, strb):
        self.data = int.from_bytes(strb,byteorder='big',signed=False) # bytes转int，big代表高位在前低位在后
        if self.data == 16:
            self.status = 1
        else:
            self.status = 0
        self.help = '应该有16个数据块对应表A.5的16个采集命令字。如果不等于16，则可能存在错误。'
        
class VDR_STANDARD_YEAR(object):
    '''
    记录仪标准版本年号
    datacode:数据代码
    dataname:数据名称
    datalength:数据长度
    year:记录仪标准年号，无应答默认为03
    danhao:修改单号，默认为00H，取值范围00~FFH
    '''
    def __init__(self, dataname, datalength, year, danhao):
        self.datacode = '00'
        self.dataname = dataname
        self.datalength = datalength
        self.year = year
        self.danhao = danhao
        if year == '03' or year == '12':
            self.status = 1
        else:
            self.status = 0
        self.help = '记录仪执行标准年号后2位应为03或者12'

class VDR_DRIVER_INFO(object):
    '''
    当前驾驶人信息
    datacode:数据代码
    dataname:数据名称
    datalength:数据长度
    driver_card_no:机动车驾驶证号码
    '''   
    def __init__(self, dataname, datalength, driver_card_no):
        self.datacode = '01'
        self.dataname = dataname
        self.datalength = datalength
        self.driver_card_no = driver_card_no
        self.help = '机动车驾驶证号码为15位时，后3位以00H补齐。驾驶人身份未知时以00H表示'
        
class VDR_TEMP_TIME(object):
    '''
    记录仪实时时间
    time:时间
    '''
    def __init__(self, dataname, datalength, year, month, day, hour, minute, second):
        self.datacode = '02'
        self.dataname = dataname
        self.datalength = datalength
        self.temp_time = VDR_TIME_DATASTRUCTURE(year, month, day, hour, minute, second)
        self.help = '范围为2000年1月1日0时0分0秒~2099年12月31日23时59分59秒'
        
class VDR_CUMULATIVE_MILEAGE(object):
    '''
    累计行驶里程
    temp_time:记录仪实时时间
    inital_install_time:初次安装时间
    init_mileage:初始里程
    cumlative_mileage:累计行驶里程
    '''
    def __init__(self, dataname, datalength, year1, month1, day1, hour1, minute1, second1, 
                 year2, month2, day2, hour2, minute2, second2, init_mileage, cumlative_mileage):
        self.datacode = '03'
        self.dataname = dataname
        self.datalength = datalength
        self.temp_time = VDR_TIME_DATASTRUCTURE(year1, month1, day1, hour1, minute1, second1)
        self.inital_install_time = VDR_TIME_DATASTRUCTURE(year2, month2, day2, hour2, minute2, second2)
        self.init_mileage = init_mileage
        self.cumlative_mileage = cumlative_mileage
        self.help = ''
        
class VDR_PULSE(object):
    '''
    脉冲系数
    temp_time:记录仪实时时间
    pulse:脉冲系数
    '''
    def __init__(self, dataname, datalength, year, month, day, hour, minute, second, pulse):
        self.datacode = '04'
        self.dataname = dataname
        self.datalength = datalength
        self.temp_time = VDR_TIME_DATASTRUCTURE(year, month, day, hour, minute, second)
        self.pulse = pulse
        self.help = ''
        
class VDR_VEHICLE_INFO(object):
    '''
    车辆信息
    recognition_no:车辆识别代号
    license_no:机动车号牌号码
    license_type:机动车号牌分类
    '''
    def __init__(self, dataname, datalength, recognization_no, license_no, license_type):
        self.datacode = '05'
        self.dataname = dataname
        self.datalength = datalength
        self.recognization_no = recognization_no
        self.license_no = license_no
        self.license_type = license_type
        self.help = ''
        

# 基本数据格式
class VDR_TIME_DATASTRUCTURE(object):
    '''
    记录仪实时时间
    time:时间
    '''
    def __init__(self, year, month, day, hour, minute, second):
        self.year = year
        self.month = month
        self.day = day
        self.hour = hour
        self.minute = minute
        self.second = second
        self.time = self.__construct_time()
        self.help = '范围为2000年1月1日0时0分0秒~2099年12月31日23时59分59秒'
        
    def __construct_time(self):
        return self.year+'年'+self.month+'月'+self.day+'日'+self.hour+'时'+self.minute+'分'+self.second+'秒'

        
if __name__ == "__main__":
    vdr_object = VDR_OBJECT('D210315_0939_B123456.VDR')
    print(vdr_object.datablock_num.data)
    print(vdr_object.standard_year.year)